// Item behaviours
//--------------------------------
#ifndef BITEM_H
#define BITEM_H
#include "behaviour.h"
#include "buff.h"

// Called to find the item object of a
// physical representation of an item
// Param item - item pointer return
class BIIsItem : public BIConst< Item** > {
public:

    BEHAVIOUR_CALL const
    {
        return IsItem( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = 0;
    }
    BEHAVIOUR_END { }

protected:

    virtual bool IsItem( Item** item ) const = 0;

};

class BIItemCategory : public BIConst< uint* > {
public:

    // Purely aesthetic categorisation
    enum Category {
        WEAPON,
        ARMOUR,
        ACCESSORY,
        CONSUMABLE,
        RUNE,
        OTHER,
        MAX_CATEGORY
    };

    BEHAVIOUR_CALL const
    {
        return ItemCategory( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = OTHER;
    }
    BEHAVIOUR_END { }

protected:

    virtual bool ItemCategory( uint* category ) const = 0;

};

class BIItemType : public BIConst< uint* > {
public:

    // Affects how the item can be manipulated
    enum Type {
        WEARABLE_HEAD         = 1,
        WEARABLE_BODY         = 2,
        WEARABLE_FEET         = 4,
        WEARABLE_HAND         = 8,
        WEARABLE_RING         = 16,
        WEARABLE_NECK         = 32,
        WEARABLE              = WEARABLE_NECK | WEARABLE_RING | WEARABLE_HAND | WEARABLE_FEET | WEARABLE_BODY | WEARABLE_HEAD,
        WIELDABLE_1H          = 64,
        WIELDABLE_2H          = 128,
        WIELDABLE             = WIELDABLE_1H | WIELDABLE_2H
    };

    BEHAVIOUR_CALL const
    {
        return ItemType( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = 0;
    }
    BEHAVIOUR_END { }

protected:

    virtual bool ItemType( uint* type ) const = 0;

};

class BIItemWeight : public BIConst< uint* > {
public:

    BEHAVIOUR_CALL const
    {
        return ItemWeight( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = 0;
    }
    BEHAVIOUR_END { }

protected:

    virtual bool ItemWeight( uint* weight ) const = 0;

};

class BIOnEquip : public BI< bool > {
public:

    BEHAVIOUR_CALL
    {
        return OnEquip( a0 );
    }

    BEHAVIOUR_START { }
    BEHAVIOUR_END { }

protected:

    virtual bool OnEquip( bool wield ) = 0;

};

class BIItemSymbol : public BIConst< IO::Sym* > {
public:

    BEHAVIOUR_CALL const
    {
        return ItemSymbol( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = IO::Sym( Sym::QUESTION, Colour( 255, 255, 255 ) );
    }
    BEHAVIOUR_END { }

protected:

    virtual bool ItemSymbol( IO::Sym* symbol ) const = 0;

};

class BIOnUpdateBuffs : public BI<> {
public:

    BEHAVIOUR_CALL
    {
        return OnUpdateBuffs();
    }

    BEHAVIOUR_START { }
    BEHAVIOUR_END { }

protected:

    virtual bool OnUpdateBuffs() = 0;

};

class BIItemCarrier : public BIConst< Creature**, bool*, bool* > {
public:

    BEHAVIOUR_CALL const
    {
        return ItemCarrier( a0, a1, a2 );
    }

    BEHAVIOUR_START
    {
        *a0 = 0;
        *a1 = false;
        *a2 = false;
    }
    BEHAVIOUR_END { }

protected:

    virtual bool ItemCarrier( Creature** carrier, bool* worn, bool* wielded ) const = 0;

};

class BIOnIdentify : public BI<> {
public:

    BEHAVIOUR_CALL
    {
        return OnIdentify();
    }

    BEHAVIOUR_START { }
    BEHAVIOUR_END { }

protected:

    virtual bool OnIdentify() = 0;

};

class BIOnEaten : public BI< Creature* > {
public:

    BEHAVIOUR_CALL
    {
        return OnEaten( a0 );
    }

    BEHAVIOUR_START { }
    BEHAVIOUR_END { }

protected:

    virtual bool OnEaten( Creature* creature ) = 0;

};

class BICreateWieldBuff : public BIConst< CompoundBuff** > {
public:

    BEHAVIOUR_CALL const
    {
        return CreateWieldBuff( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = new CompoundBuff();
    }
    BEHAVIOUR_END { }

protected:

    virtual bool CreateWieldBuff( CompoundBuff** buff ) const = 0;

};

class BICreateWearBuff : public BIConst< CompoundBuff** > {
public:

    BEHAVIOUR_CALL const
    {
        return CreateWearBuff( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = new CompoundBuff();
    }
    BEHAVIOUR_END { }

protected:

    virtual bool CreateWearBuff( CompoundBuff** buff ) const = 0;

};

class BICreateHoldBuff : public BIConst< CompoundBuff** > {
public:

    BEHAVIOUR_CALL const
    {
        return CreateHoldBuff( a0 );
    }

    BEHAVIOUR_START
    {
        *a0 = new CompoundBuff();
    }
    BEHAVIOUR_END { }

protected:

    virtual bool CreateHoldBuff( CompoundBuff** buff ) const = 0;

};

#endif